package org.vacoor.nothing.misc.express.usps.api.support;

import org.vacoor.nothing.common.xml.JAXP;
import org.vacoor.nothing.misc.express.usps.api.UspsException;
import org.vacoor.nothing.misc.express.usps.api.UspsRequest;
import org.vacoor.nothing.misc.express.usps.api.UspsResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import java.io.StringReader;

/**
 */
public abstract class AbstractUspsResultBuilder<T> implements UspsResult.Builder<T> {

    @Override
    public UspsResult<T> build(final UspsRequest req, final String responseXml) {
        try {
            DocumentBuilder builder = JAXP.createDOMBuilder(null);
            Document doc = builder.parse(new InputSource(new StringReader(responseXml)));
            Element root = doc.getDocumentElement();

            if ("Error".equals(root.getNodeName())) {
                XPathFactory xPathFactory = XPathFactory.newInstance();
                XPath xPath = xPathFactory.newXPath();
                String errorCode = xPath.evaluate("/Error/Number/text()", root);
                String errorReason = xPath.evaluate("/Error/Description/text()", root);
                String errorSource = xPath.evaluate("/Error/Source/text()", root);
                return UspsResult.failed(req, responseXml, errorCode, errorReason, errorSource);
            } else {
                T t = buildTarget(req, responseXml);
                return UspsResult.success(req, responseXml, t);
            }
        } catch (Exception e) {
            throw new UspsException(e);
        }
    }

    protected abstract T buildTarget(final UspsRequest req, final String responseXml);
}
